#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <lv_conf_board.h>

// #include "drv_delay.h"
#include "drv_mipi_dsi_host.h"
#include "dpu.h"
#include "mm_config.h"

#define FEATURE_EG_360_SHOW_BOOT_LOGO 0

//#ifdef APP_DEMO
#ifdef DPULAYER_USECASE0
/*
no bootlogo in layer0
rgb camera -> dpu layer0
set picture -> dpu layer1
ir camera -> dpu layer2
lvgl      -> dpu layer3
*/
#ifdef FEATURE_EG_360_SHOW_BOOT_LOGO
#undef FEATURE_EG_360_SHOW_BOOT_LOGO
#define FEATURE_EG_360_SHOW_BOOT_LOGO 0
#endif

#else
/*
rgb camera -> dpu layer1
set picture -> dpu layer2
no ir camera
lvgl  -> dpu layer3
*/
#endif  /* APP_DEMO */


#define TEST_DPU_RGBA(r,g,b,a) ((r)<<24 | (g)<<16 | (b)<< 8 | a)
typedef enum {
    TEST_DPU_RGBA_BLACK = TEST_DPU_RGBA(0x00,0x00,0x00,0xff),
    TEST_DPU_RGBA_RED   = TEST_DPU_RGBA(0xff,0x00,0x00,0xff),
    TEST_DPU_RGBA_GREEN = TEST_DPU_RGBA(0x00,0xff,0x00,0xff),
    TEST_DPU_RGBA_BLUE  = TEST_DPU_RGBA(0x00,0x00,0xff,0xff),
    TEST_DPU_RGBA_WHITE = TEST_DPU_RGBA(0xff,0xff,0xff,0xff),
} dpu_rgba_e;


static dpu_handle_t dpu_handle = NULL;
char *g_layer2_buf = NULL;



#define BUF_ADDR_LAYER2 MM_IMG_ISP0_BUF0

static const dpu_layer_cfg_t dpu_layer2_cfg_default = {
    .resx      = 720,
    .resy      = 1280,
    .colormode = DPU_COLORMODE_ARGB8888,
    .blendmode = DPU_BLENDMODE_SIMPLE,
    .startx    = 0,
    .starty    = 0,
    .sizex     = LV_HOR_RES_MAX,
    .sizey     = LV_VER_RES_MAX,
    .alpha     = 0,
    .baseaddr  = (void *)BUF_ADDR_LAYER2,
};
    




void dpu_layer_extra_config(void)
{
#ifdef DPULAYER_USECASE0
/* rgb camera->dpu layer0; set picture->layer1; ir camera->layer2; lvgl->layer3 */
	// dpu_layer_cfg_t cfg;
	// const uint8_t layer_id = 2;
#endif
}

#if 0
static void dpu_setup(void)
{
    int i;

    /* Set background colour to be black */
    dpu_rgba32_t rgba = TEST_DPU_RGBA_BLACK;
    csi_dpu_set_bgcolor(dpu_handle, rgba);

    for (i = 0; i < 4; i++)
        csi_dpu_layer_enable(dpu_handle, i, 0);

}
#endif

int dpu_layer_config(uint8_t layer_id, dpu_layer_cfg_t *layer_cfg)
{
    int ret;
    dpu_layer_cfg_t cfg_read;

    ret = csi_dpu_layer_set_config(dpu_handle, layer_id, layer_cfg);
    if (ret) {
        printf("csi_dpu_layer_set_config() error.\r\n");    
        return ret;
    }
   
    ret = csi_dpu_layer_get_config(dpu_handle, layer_id, &cfg_read);
    if(memcmp(layer_cfg, &cfg_read, sizeof(dpu_layer_cfg_t)) != 0) {
        printf("compare dpu cfg error.\r\n");    
        return -1;        
    }

    ret = csi_dpu_layer_enable(dpu_handle, layer_id, 1);
    if (ret) {
        printf("csi_dpu_layer_enable() error.\r\n");
        return ret;
    }
    
    return ret;
}


int dpu_init(EM_LCD_TYPE lcd_type)
{
    int32_t ret;
    dpu_cfg_display_timing_t timing;
    dpu_cfg_display_signal_polarity_t polarity;
    mipi_dsi_host_config_t lcd_para;

    
    dpu_handle = csi_dpu_initialize(0, NULL, NULL);
    if (dpu_handle == NULL) {
        printf("csi_dpu_initialize() null.\r\n");
        return -1;
    }
    
    ret = lcd_get_cfg(lcd_type, &lcd_para);
    if (ret) {
        printf("mipi_lcd_get_cfg() err.\r\n");
        return -1;
    }


    timing.resolution_x = lcd_para.timing.resolution_x;       
    timing.resolution_y = lcd_para.timing.resolution_y;     
    timing.hsync_width = lcd_para.timing.hsync_width;          
    timing.vsync_width = lcd_para.timing.vsync_width;         
    timing.front_porch_x = lcd_para.timing.front_porch_x;      
    timing.front_porch_y = lcd_para.timing.front_porch_y;       
    timing.back_porch_x = lcd_para.timing.back_porch_x;       
    timing.back_porch_y = lcd_para.timing.back_porch_y;   
    polarity.hsync = DPU_SIGNAL_ACTIVE_HIGH;
    polarity.vsync = DPU_SIGNAL_ACTIVE_HIGH;
    polarity.deta_enable = DPU_SIGNAL_ACTIVE_HIGH;
    polarity.pixel_clock = DPU_SIGNAL_ACTIVE_HIGH;
    ret = csi_dpu_config_display(dpu_handle, &timing, &polarity);
    if (ret) {
        printf("csi_dpu_config_display() error.\r\n");
        return -1;
    }

    ret = csi_dpu_dpi2_cfg(dpu_handle, DPU_DPI_2_RGB888);
    if (ret) {
        printf("csi_dpu_dpi2_cfg() error.\r\n");
        return -1;
    }


	csi_dpu_layer_enable(dpu_handle, 0, 1);

    csi_dpu_layer_set_config(dpu_handle, 0, (dpu_layer_cfg_t *)&dpu_layer2_cfg_default);

    ret = csi_dpu_start(dpu_handle);
    if (ret) {
        printf("csi_dpu_start() error.\r\n");
        return -1;
    }

    //dpu_setup();
	

    
    return 0;
}


